/*
   Copyright (c) 2015 Mizar Tools Contributors (mizartools.org)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
/*  Contributors :
 *	2015-02-07 Marco Riccardi - initial implementation
 *  
 */

package org.mizartools.dli.utility;

import java.util.LinkedHashMap;
import java.util.LinkedList;

import org.mizartools.dli.Aggregate;
import org.mizartools.dli.AggregateNotation;
import org.mizartools.dli.Attribute;
import org.mizartools.dli.AttributeNotation;
import org.mizartools.dli.ConditionalRegistration;
import org.mizartools.dli.DecodedLibraryItem;
import org.mizartools.dli.Definiens;
import org.mizartools.dli.DliException;
import org.mizartools.dli.DliParseException;
import org.mizartools.dli.ExistentialRegistration;
import org.mizartools.dli.ForgNotation;
import org.mizartools.dli.Functor;
import org.mizartools.dli.FunctorNotation;
import org.mizartools.dli.IdentifyRegistration;
import org.mizartools.dli.ItemType;
import org.mizartools.dli.Mode;
import org.mizartools.dli.ModeNotation;
import org.mizartools.dli.Predicate;
import org.mizartools.dli.PredicateNotation;
import org.mizartools.dli.ReductionRegistration;
import org.mizartools.dli.Scheme;
import org.mizartools.dli.Selector;
import org.mizartools.dli.SelectorNotation;
import org.mizartools.dli.Sethood;
import org.mizartools.dli.Structure;
import org.mizartools.dli.StructureNotation;
import org.mizartools.dli.TermAdjectiveRegistration;
import org.mizartools.dli.Theorem;

public class Exporter {

	private LinkedList<String> item = new LinkedList<String>();

	private LinkedHashMap<String, String> attributeNotation = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> aggregateNotation = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> forgNotation = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> functorNotation = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> modeNotation = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> predicateNotation = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> selectorNotation = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> structureNotation = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> aggregate = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> attribute = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> definiens = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> functor = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> mode = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> predicate = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> selector = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> structure = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> scheme = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> theorem = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> definitionalTheorem = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> conditionalRegistration = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> existentialRegistration = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> identifyRegistration = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> reductionRegistration = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> sethood = new LinkedHashMap<String, String>();
	private LinkedHashMap<String, String> termAdjectiveRegistration = new LinkedHashMap<String, String>();

	public LinkedList<String> getItem(){return item;}
	
	public LinkedHashMap<String, String> getAggregateNotation(){return aggregateNotation;}
	public LinkedHashMap<String, String> getAttributeNotation(){return attributeNotation;}
	public LinkedHashMap<String, String> getForgNotation(){return forgNotation;}
	public LinkedHashMap<String, String> getFunctorNotation(){return functorNotation;}
	public LinkedHashMap<String, String> getModeNotation(){return modeNotation;}
	public LinkedHashMap<String, String> getPredicateNotation(){return predicateNotation;}
	public LinkedHashMap<String, String> getSelectorNotation(){return selectorNotation;}
	public LinkedHashMap<String, String> getStructureNotation(){return structureNotation;}

	public LinkedHashMap<String, String> getAggregate(){return aggregate;}
	public LinkedHashMap<String, String> getAttribute(){return attribute;}
	public LinkedHashMap<String, String> getDefiniens(){return definiens;}
	public LinkedHashMap<String, String> getFunctor(){return functor;}
	public LinkedHashMap<String, String> getMode(){return mode;}
	public LinkedHashMap<String, String> getPredicate(){return predicate;}
	public LinkedHashMap<String, String> getSelector(){return selector;}
	public LinkedHashMap<String, String> getStructure(){return structure;}
	public LinkedHashMap<String, String> getScheme(){return scheme;}
	public LinkedHashMap<String, String> getTheorem(){return theorem;}
	public LinkedHashMap<String, String> getDefinitionalTheorem(){return definitionalTheorem;}

	public LinkedHashMap<String, String> getConditionalRegistration(){return conditionalRegistration;}
	public LinkedHashMap<String, String> getExistentialRegistration(){return existentialRegistration;}
	public LinkedHashMap<String, String> getIdentifyRegistration(){return identifyRegistration;}
	public LinkedHashMap<String, String> getReductionRegistration(){return reductionRegistration;}
	public LinkedHashMap<String, String> getSethood(){return sethood;}
	public LinkedHashMap<String, String> getTermAdjectiveRegistration(){return termAdjectiveRegistration;}
	
	public void put(String value) throws DliException, DliParseException {
		DecodedLibraryItem decodedLibraryItem = DecodedLibraryItem.newInstance(value);
		String key = decodedLibraryItem.getItemId().toString();
		if (item.contains(key)){
			throw new DliException();
		} else
		{
			item.add(key);
		}
		if (decodedLibraryItem.getItemDefinition() instanceof PredicateNotation) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.prednot) {
				if (predicateNotation.containsKey(key)) {
					throw new DliException();
				} else {
					predicateNotation.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof AggregateNotation) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.aggrnot) {
				if (aggregateNotation.containsKey(key)) {
					throw new DliException();
				} else {
					aggregateNotation.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof AttributeNotation) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.attrnot) {
				if (attributeNotation.containsKey(key)) {
					throw new DliException();
				} else {
					attributeNotation.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof ForgNotation) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.forgnot) {
				if (forgNotation.containsKey(key)) {
					throw new DliException();
				} else {
					forgNotation.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof FunctorNotation) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.funcnot) {
				if (functorNotation.containsKey(key)) {
					throw new DliException();
				} else {
					functorNotation.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof ModeNotation) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.modenot) {
				if (modeNotation.containsKey(key)) {
					throw new DliException();
				} else {
					modeNotation.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof SelectorNotation) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.selnot) {
				if (selectorNotation.containsKey(key)) {
					throw new DliException();
				} else {
					selectorNotation.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof StructureNotation) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.structnot) {
				if (structureNotation.containsKey(key)) {
					throw new DliException();
				} else {
					structureNotation.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof Aggregate) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.aggr) {
				if (aggregate.containsKey(key)) {
					throw new DliException();
				} else {
					aggregate.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof Attribute) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.attr) {
				if (attribute.containsKey(key)) {
					throw new DliException();
				} else {
					attribute.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof Definiens) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.dfs) {
				if (definiens.containsKey(key)) {
					throw new DliException();
				} else {
					definiens.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof Functor) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.func) {
				if (functor.containsKey(key)) {
					throw new DliException();
				} else {
					functor.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof Mode) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.mode) {
				if (mode.containsKey(key)) {
					throw new DliException();
				} else {
					mode.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof Predicate) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.pred) {
				if (predicate.containsKey(key)) {
					throw new DliException();
				} else {
					predicate.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof Scheme) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.sch) {
				if (scheme.containsKey(key)) {
					throw new DliException();
				} else {
					scheme.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof Selector) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.sel) {
				if (selector.containsKey(key)) {
					throw new DliException();
				} else {
					selector.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof Structure) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.struct) {
				if (structure.containsKey(key)) {
					throw new DliException();
				} else {
					structure.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof Theorem) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.def) {
				if (definitionalTheorem.containsKey(key)) {
					throw new DliException();
				} else {
					definitionalTheorem.put(key, value);
				}
			} else if (decodedLibraryItem.getItemId().getItemType() == ItemType.th) {
				if (theorem.containsKey(key)) {
					throw new DliException();
				} else {
					theorem.put(key, value);
				}
			} else {
				throw new DliException();
			}
		} else if (decodedLibraryItem.getItemDefinition() instanceof ConditionalRegistration) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.condreg) {
				if (conditionalRegistration.containsKey(key)) {
					throw new DliException();
				} else {
					conditionalRegistration.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof ExistentialRegistration) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.exreg) {
				if (existentialRegistration.containsKey(key)) {
					throw new DliException();
				} else {
					existentialRegistration.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof IdentifyRegistration) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.idreg) {
				if (identifyRegistration.containsKey(key)) {
					throw new DliException();
				} else {
					identifyRegistration.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof TermAdjectiveRegistration) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.funcreg) {
				if (termAdjectiveRegistration.containsKey(key)) {
					throw new DliException();
				} else {
					termAdjectiveRegistration.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof ReductionRegistration) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.redreg) {
				if (reductionRegistration.containsKey(key)) {
					throw new DliException();
				} else {
					reductionRegistration.put(key, value);
				}
			} else throw new DliException();
		} else if (decodedLibraryItem.getItemDefinition() instanceof Sethood) {
			if (decodedLibraryItem.getItemId().getItemType() == ItemType.sethood) {
				if (sethood.containsKey(key)) {
					throw new DliException();
				} else {
					sethood.put(key, value);
				}
			} else throw new DliException();
		} else {
			throw new DliException();
		}
	}
	
	
}
